package com.gitee.ly.ymorm.executor.handler;

import com.gitee.ly.ymorm.exceptions.YmOrmException;
import com.gitee.ly.ymorm.executor.Executor;
import com.gitee.ly.ymorm.mapping.BoundSql;
import com.gitee.ly.ymorm.mapping.ParamMap;
import com.gitee.ly.ymorm.mapping.YmOrmStatement;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

/**
 * RoutingStatementHandler
 *
 * @author ly
 **/
public class RoutingStatementHandler implements StatementHandler {

    private final StatementHandler delegate;

    public RoutingStatementHandler(Executor executor, YmOrmStatement ymOrmStatement, ParamMap parameterObject, BoundSql boundSql) {
        switch (ymOrmStatement.getStatementType()) {
            case STATEMENT:
                delegate = new SimpleStatementHandler(executor, ymOrmStatement, parameterObject, boundSql);
                break;
            case PREPARED:
                delegate = new PreparedStatementHandler(executor, ymOrmStatement, parameterObject, boundSql);
                break;
            case CALLABLE:
                delegate = new CallableStatementHandler(executor, ymOrmStatement, parameterObject, boundSql);
                break;
            default:
                throw new YmOrmException("Unknown statement type: " + ymOrmStatement.getStatementType());
        }
    }

    @Override
    public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
        return delegate.prepare(connection, transactionTimeout);
    }

    @Override
    public void parameterize(Statement statement) throws SQLException {
        delegate.parameterize(statement);
    }

    @Override
    public void batch(Statement statement) throws SQLException {
        delegate.batch(statement);
    }

    @Override
    public int update(Statement statement) throws SQLException {
        return delegate.update(statement);
    }

    @Override
    public <E> List<E> query(Statement statement, Class<? extends E> resultType) throws SQLException {
        return delegate.query(statement, resultType);
    }

    @Override
    public BoundSql getBoundSql() {
        return delegate.getBoundSql();
    }
}
